package toolz;
import java.util.Arrays;

public class EfficientMedianFilterLined {



	public static double[][] multithreadFilter(final double[][] map) {

		int xDim = map.length;
		int yDim = map[0].length;
		final int maskSize = 5;
		final int medianPos = ((maskSize * maskSize + 1) / 2) - 1;
		double[][] newArray = new double[xDim][yDim];
		
		for (int y = 0; y < newArray[0].length; y++) {
		//for (int x = 0; x < newArray.length; x++) {
			MedianLineProcessor t = new MedianLineProcessor(map, maskSize, medianPos, newArray, y);
			t.start();
		}
		return (newArray);
	}

	static class MedianLineProcessor extends Thread{
		private double[][] map;
		private int maskSize;
		private int medianPos;
		private double[][] newArray;
		private int y;
		
		public MedianLineProcessor(double[][] map, int maskSize, int medianPos, double[][] newArray, int y) {
			super();
			this.map = map;
			this.maskSize = maskSize;
			this.medianPos = medianPos;
			this.newArray = newArray;
			this.y = y;
		}

		@Override
		public void run() {
			double[] elements = new double[maskSize * maskSize];
			for (int x = 0; x < newArray.length; x++) {
			//for (int y = 0; y < newArray[0].length; y++) {
				newArray[x][y] = getMedianOfArea(map, maskSize, medianPos, elements, x, y);
			}
		}
	}

	private static double getMedianOfArea(double[][] map, int maskSize, int medianPos, double[] elements, int x, int y) {
		int xDim = map.length;
		int yDim = map[0].length;
		int maskR = (maskSize - 1) / 2;
		int eC = 0;
		
		for (int mx = maskR * -1; mx <= maskR; mx++) {
			for (int my = maskR * -1; my <= maskR; my++) {
				if ((x + mx >= 0) && (y + my >= 0) && (x + mx < xDim) && (y + my < yDim)) {
					elements[eC] = map[x + mx][y + my];
				} else
					elements[eC] = 0;
				eC++;
			}
		}
		Arrays.sort(elements);
		return elements[medianPos]; // median
	}
	
}
